package com.jbm.core.common;

import com.google.protobuf.GeneratedMessage;
import com.jbm.core.iface.IAcross;
import com.jbm.core.pb.PBIAcross;
import com.jbm.core.pb.PBIFileObject;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;

import java.io.RandomAccessFile;
import java.net.InetSocketAddress;

/**
 * Created by root on 17-5-24.
 */
public class IoSessionShell
{
	public IoSessionShell()
	{
		m_iosession = null;
		m_ca = null;
		m_server_type = (char)-1;
		m_response_type = (char)-1;
	}

	public IoSessionShell( IoSession ios, ConnectAgent ca, char server_type )
	{
		this();

		m_iosession = ios;
		m_ca = ca;
		m_server_type = server_type;

		if ( server_type == MainServer.Server_type_Server )
			m_response_type = MainServer.Server_type_Client;
		else
			m_response_type = MainServer.Server_type_Server;
	}

	public WriteFuture Swrite(Object var1)
	{
		synchronized (m_ios_mutex)
		{
			IAcross request = null;

			if ( var1.getClass().getSimpleName().equals("IAcross"))
				if (( ( (PBIAcross.IAcross)var1).getExcode() & IAcross.excode_doexcode ) != 0 )
				{
					request = new TransClass().PB2_0toI2_0("ExCode:", (PBIAcross.IAcross) var1);

					try
					{
						GeneratedMessage gm = (GeneratedMessage) request.PreEncode(((PBIAcross.IAcross) var1).getContent());
						var1 = ((PBIAcross.IAcross) var1).toBuilder().setContent(gm.toByteString()).build();
					}catch (Exception e)
					{
						return null;
					}
				}

			if ( m_iosession != null )
				if ( var1.getClass().getSimpleName().equals("IAcross"))
					if (( ( (PBIAcross.IAcross)var1).getExcode() & IAcross.excode_doexcode ) != 0 )
					{
						try
						{
							WriteFuture wf = m_iosession.write(var1);
							wf.awaitUninterruptibly();

							request.Encode(this, ((PBIAcross.IAcross)var1).getContent(),(PBIAcross.IAcross)var1);
						}catch (Exception e)
						{
						}

						return null;
					}else
						return m_iosession.write(var1);
				else
					return m_iosession.write(var1);
			else if ( m_ca != null &&
					MainServer.getG_server().getM_server_type() == MainServer.Server_type_Server )
			{
				int local_id = MainServer.getG_server().getM_local_id();

				if (m_server_type == MainServer.Server_type_Server)
				{
					IAccount ia = m_ca.getM_iaccount();

					if ( ia != null )
						local_id = ia.getM_account_id();
					else
						local_id = 0;
				}

				if ( var1.getClass().getSimpleName().equals("IAcross"))
					if (( ( (PBIAcross.IAcross)var1).getExcode() & IAcross.excode_doexcode ) != 0 )
					{
						PBIAcross.IAcross iacross = (PBIAcross.IAcross)var1;

						request = new TransClass().PB2_0toI2_0("ExCode:", iacross);

						try
						{
							GeneratedMessage gm = (GeneratedMessage) request.StartDecode(iacross.getContent(), new IoSessionShell(null, m_ca, m_response_type));

							if (gm != null)
							{
								PBIAcross.IAcross.Builder iab = iacross.toBuilder();

								iab.setContent(gm.toByteString());
								iacross = iab.build();
								request.setIAcross(iacross);

								m_ca.getM_excodemap().put((Integer) (iacross.getQindex() & 0x7fff), request);
							} else
							{
								PBIAcross.IAcross pbresponse = new PBRandR(iacross).BuildResponse(new IAcross(500, "附件处理错误"));

								new IoSessionShell(null, m_ca, m_response_type).Swrite(pbresponse);
							}

							request.Encode(this, ((PBIAcross.IAcross) var1).getContent(), iacross);
						}catch (Exception e)
						{
						}

						return null;
					}else
						AutoCall.g_autocall.IO(null,m_ca,(PBIAcross.IAcross)var1,local_id,m_response_type);
				else if ( var1 instanceof OHByte )
				{
					try
					{
						OHByte ohbyte = (OHByte) var1;

						IAcross ia = m_ca.getM_excodemap().get((Integer) (ohbyte.pbia.getQindex() & 0x7fff));

						PBIAcross.IAcross pbia = null;

						if (ia != null)
						{
							if (ia.Decode(ohbyte.buffer))
								pbia = (PBIAcross.IAcross) ia.getIAcross();
						} else
							return null;

						if (pbia != null)
						{
							AutoCall.g_autocall.IO(null, m_ca, pbia, local_id, m_response_type);
							m_ca.getM_excodemap().remove((Integer) (ohbyte.pbia.getQindex() & 0x7fff));
						} else
							return null;
					}catch (Exception e)
					{
					}
				}

				return null;
			}else
				return null;
		}
	}

	public boolean SisConnected()
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return m_iosession.isConnected();
			else
				return false;
		}
	}

	public CloseFuture Sclose(boolean c)
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return m_iosession.close(c);
			else
				return null;
		}
	}

	public String getRemoteIP()
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return ((InetSocketAddress) m_iosession.getRemoteAddress()).getAddress().getHostAddress();
			else
				return null;
		}
	}

	public int getRemotePort()
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return ((InetSocketAddress) m_iosession.getRemoteAddress()).getPort();
			else
				return -1;
		}
	}

	public int getLocalPort()
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return ((InetSocketAddress) m_iosession.getLocalAddress()).getPort();
			else
				return -1;
		}
	}

	public Object SgetAttribute(Object key)
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return m_iosession.getAttribute(key);
			else
				return null;
		}
	}

	public Object SsetAttribute(Object key, Object value)
	{
		synchronized (m_ios_mutex)
		{
			if ( m_iosession != null )
				return m_iosession.setAttribute(key, value);
			else
				return null;
		}
	}

	public ConnectAgent getM_ca()
	{
		return m_ca;
	}

	public IoSession getM_iosession()
	{
		return m_iosession;
	}

	public char getM_server_type()
	{
		return m_server_type;
	}

	private IoSession m_iosession;
	private ConnectAgent m_ca;
	private char m_server_type;
	private char m_response_type;
	private Object m_ios_mutex = new Object();
}
